
grammar SimpleExpr; //程序名称和.g4名称一致即可
@header {        //一种action,定义生成的词法语法解析文件的头，当使用java的时候，生成的类需要包名，可以在这里统一定义
 package com.taotao.antlr4;
}

//  一个程序由若干个语句构成，EOF 是结束符表示程序结束
prog : stat* EOF ;

// 描述语句:由表达式+分号结尾。字面量都由单引号包围; 小写开头的是语法规约，大写开头的是词法规约
stat : expr SEMI
        | ID EQUAL expr SEMI   // 赋值语句
        | PRINT expr SEMI  // 打印语句
        ;

// 描述表达式
expr : expr (MUL | DIV) expr   // 乘除表达式。小括号包围的是子规则
        | expr (ADD | SUB) expr   // 加减表达式。 乘除表达式 表示 乘除 运算优先级比加减高；antlr 规定写在前面的表达式优先级高
        | LPAREN expr RPAREN    // 括号
        | ID      // 标识符
        | INT  // 整数
        | FLOAT
        ;
// 凡是放在单引号中的字面量，antlr会自动生成词法规则，自动生成的词法规则默认在词法的最前面。建议引号中的字面量也生成词法规则，可以用插件的generate功能帮忙生成


// 字面量
SEMI : ';' ;
EQUAL : '=' ;
PRINT : 'print' ;
MUL : '*' ;
DIV : '/' ;
ADD : '+' ;
SUB : '-' ;
LPAREN : '(' ;
RPAREN : ')' ;



// 标识符：仅能由下划线或字母开头且由下划线字母或数字组成
ID : ('_' | LETTER) WORD*;
// 整数
INT : '0' | (ADD | SUB)? [1-9]NUMBER* ;
// 浮点数
FLOAT : INT '.' NUMBER+  ;


// 文档注释  antlr 有最前规则优先匹配的原则，所以 文档注释要写在多行注释前面
DOC_COMMENT : '/**' (~'\n')* '*/'  -> skip ;
// 单行注释定义   (~'\n')* 表示非换行符的任意字符
SL_COMMENT : '//' (~'\n')* '\n'  -> skip ;
// 多行注释
ML_COMMENT : '/*' (~'\n')* '*/'  -> skip ;


//4个空白字符  ->skip表示antlr4在分析语言的文本时，符合这个规则的词法将被无视
WS : [ \t\n\r]+ -> skip ;


// 语法片段 可以作为替换词法中相同的部分
fragment LETTER : [a-zA-Z];
fragment NUMBER : [0-9];
fragment WORD : '_' | LETTER | NUMBER;


